﻿using Newtonsoft.Json.Serialization;
using Sustainalytics.Synchronization.Interface;
using System;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;

namespace Sustainalytics.Governance.Synchronization
{
    public class GenerateCompanyReportsSyncStep : ISyncStep
    {
        public SyncStepOrder ExecutionOrder => SyncStepOrder.GenerateGovernanceCompanyReports;

        public SyncContext Start(SyncContext syncContext)
        {
            var serviceAddress = GetGovernanceServiceAddress();

            GenerateReports(syncContext, serviceAddress);

            return syncContext;
        }

        private static Uri GetGovernanceServiceAddress()
        {
            if (ConfigurationManager.AppSettings["GovernanceServiceAddress"] == null)
                throw new Exception("No setting key found for GovernanceServiceAddress");

            var governanceServiceAddress = ConfigurationManager.AppSettings["GovernanceServiceAddress"];

            return new Uri(governanceServiceAddress);
        }

        private static void GenerateReports(SyncContext syncContext, Uri uri)
        {
            if (uri == null)
                throw new ArgumentNullException("uri");

            var databaseGroup = GetDatabaseGroup(syncContext);

            var jsonMediaTypeFormatter = new JsonMediaTypeFormatter
            {
                SerializerSettings =
                {
                    ContractResolver = new CamelCasePropertyNamesContractResolver()
                }
            };

            using (var client = new HttpClient())
            {
                client.Timeout = new TimeSpan(1, 0, 0);

                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                var result = client.PostAsync(uri, databaseGroup, jsonMediaTypeFormatter).Result;

                var log = result.Content.ReadAsStringAsync().Result;
                var messages = log.Split(',').ToList();
                messages.ForEach(syncContext.Log);

                if (!result.IsSuccessStatusCode)
                {
                    throw new Exception($"Failed to generate bulk company reports. Exceptions: {log}");
                }
            }
        }

        private static string GetDatabaseGroup(SyncContext syncContext)
        {
            if (syncContext.GAConnectionStrings == null || syncContext.GAConnectionStrings.Count == 0)
                throw new ArgumentException(
                    "Connection strings must be provided in order to create repositories!");

            string connectionString;

            if (!syncContext.GAConnectionStrings.TryGetValue("GovernanceDW", out connectionString))
            {
                throw new ArgumentException("No connection string found for GovernanceDW!");
            }

            string databaseGroup = null;

            if (connectionString.Contains("GovernanceDW_A"))
                databaseGroup = "A";

            if (connectionString.Contains("GovernanceDW_B"))
                databaseGroup = "B";

            return databaseGroup;
        }
    }
}
